home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / PrintingLibraries / QuickDrawShapes.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  9.5 KB  |  329 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.      File:        GXGraphics.h
  4.  
  5.      Contains:    QuickDraw GX to PostScript conversion code.
  6.                      This module contains handy printing library routines.
  7.  
  8.      Version:    Technology:    Quickdraw GX 1.1.x
  9.       
  10.      Copyright:    © 1995-1997 by Apple Computer, Inc., all rights reserved.
  11. */
  12.  
  13.  
  14. /*************
  15.  
  16.         ******************* QuickDraw Shape Stuff *******************
  17.         
  18.         The QuickDraw Shape type.
  19.         Implemented here as a rectangle shape with a tag.
  20.         The quickDrawPictStruct is the geometry of the QD shape.
  21.         This is a private structure.  There is a public API
  22.         for setting and getting the relevant information.
  23.         
  24.         The DrawShape is the tricky part:
  25.             First, if the shape not picture or a QD shape, the real GXDrawShape is just called.
  26.             If it is a picture, my cheezy picture traversal code is used.  This code maintains 
  27.             the transform hiearchy and viewports of the parent picture.  (Actually only transform
  28.             mappings are obeyed, clips are ignored - just lazy I guess.  The real gx graphics Traverse
  29.             Picture code will ultimately be used so don't worry.
  30.             
  31.             The QuickDrawShape is drawn in the following manner:
  32.                 A picture is created that has the same transform as the QuickDraw shape does.
  33.                 The translator is then installed in a port and the QD pict is drawn.
  34.                 The translator sends the shape to the callback.
  35.                 The callback makes the one shape in the above mentioned picture the shape passed in.
  36.                 The picture is then drawn.  This has the effect of making the shapes generated by
  37.                     the translator obey the transform of the QuickDraw shape.  Thus the whole PICT obeys
  38.                     the transform.  Pretty tricky, huh?
  39.         
  40. **************/
  41.  
  42.  
  43.  
  44. /****************** gx graphics integrated implementation *******************************/
  45.  
  46. #include <Aliases.h>
  47. #include <String.h>
  48. #include <GXEnvironment.h>
  49. #include "IOUtilities.h"
  50. #include "ShapeUtilities.h"
  51. #include "Private.h"
  52.  
  53. /*****************************************
  54.  
  55.         GetShapeType:
  56.         
  57.         Returns the type of a shape.
  58.         Checks for QD shapes.
  59.         
  60.         (If it is a rectangle and has the tag)
  61.         
  62. *******************************************/
  63. gxShapeType    QGXGetShapeType(gxShape source)
  64.     {
  65.         gxShapeType theType = GXGetShapeType(source);
  66.         
  67.         if ( (theType == gxRectangleType) && (GXGetShapeTags(source, gxQuickDrawPictTag, 1, gxSelectToEnd, nil) > 0) )
  68.             theType = gxQuickDrawPictType;
  69.  
  70.         return(theType);            
  71.     }
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79. /************************* Code for translation of a QuickDraw shape ******************************/
  80.  
  81.  
  82. /*** GrafPort wrapper for doing the translation so bottleneck can get to necessary information ***/
  83.  
  84. #define kQDBufferSize 1024
  85.  
  86. typedef struct {
  87.  
  88.     CGrafPort            thePort;                                // The graf port
  89.     short                    refnum;                                // file refnum.
  90.     unsigned char        buffer[kQDBufferSize];            // input buffer.
  91.     long                    bufferPosition;                    // buffer position.
  92.     long                    bufferSize;                            // Size of buffer.
  93.     OSErr                    status;                                // Place to stick error.
  94.  
  95. } TQDTranslationGrafPort;
  96.  
  97.  
  98. OSErr QGXStreamReadBuffer(TQDTranslationGrafPort *translationPort);
  99. OSErr QGXStreamReadBuffer(TQDTranslationGrafPort *translationPort)
  100.     {
  101.         OSErr            status;
  102.         long            count;
  103.                     
  104.         count = kQDBufferSize;
  105.         
  106.         status = FSRead(translationPort->refnum, &count, &(translationPort->buffer[0]));
  107.         translationPort->bufferSize = count;
  108.         translationPort->bufferPosition = 0;
  109.         
  110.         if (status == eofErr)            // end of file is okay.
  111.             status = noErr;
  112.             
  113.         ncheck(status);
  114.         return(status);
  115.         
  116.     }//QGXStreamReadBuffer
  117.  
  118.  
  119. /************
  120.     BottleNeck for spooling a PICT from disk
  121. **************/
  122. pascal void QGXGetPicProc(unsigned char *data, short count);
  123. pascal void QGXGetPicProc(unsigned char *data, short count)
  124.     {
  125.         OSErr                            status = noErr;
  126.         long                            remaining;
  127.         long                            copy;
  128.         Ptr                            dataPtr;
  129.         TQDTranslationGrafPort    *translationPort;
  130.                 
  131.         GetPort((GrafPtr *) &translationPort);
  132.         
  133.         remaining = count;
  134.         dataPtr = (Ptr)data;
  135.         while (remaining > 0) {
  136.         
  137.             if ( (translationPort->bufferSize - translationPort->bufferPosition) >= remaining) {
  138.             
  139.                 /** There is enough in the buffer to finish **/
  140.             
  141.                 BlockMoveData(&(translationPort->buffer[translationPort->bufferPosition]), dataPtr, remaining);
  142.                 translationPort->bufferPosition += remaining;
  143.                 remaining = 0;
  144.             
  145.             } else {
  146.         
  147.                 /** Copy the remainder of the buffer, read a new buffer **/
  148.  
  149.                 copy = translationPort->bufferSize - translationPort->bufferPosition;            
  150.                 BlockMoveData(&(translationPort->buffer[translationPort->bufferPosition]), dataPtr, copy);
  151.                 remaining -= copy;
  152.                 dataPtr += copy;
  153.                 
  154.                 status = QGXStreamReadBuffer(translationPort);
  155.                 nrequire(status, failed_read);
  156.                             
  157.             }//end if
  158.                     
  159.         }//end while
  160.  
  161. failed_read:
  162.         
  163.         translationPort->status = status;
  164.         
  165.         /** Maybe this will make QuickDraw stop drawing the picture **/
  166.         
  167.         if (status != noErr)
  168.             memset(data, 0xFF, (long)count);
  169.         
  170.         
  171.     }//QGXGetPicProc
  172.  
  173.  
  174.  
  175. /******************************************
  176.  
  177.     GXTranslateQuickDrawPict:
  178.     
  179.     Routine is called by a client to get individual
  180.     GX shapes from the QD pict.  The shapes are handed 
  181.     to the client using the callback and the refcon in 
  182.     the same manner that installing the translator on a
  183.     grafPort does.
  184.     
  185.     This routine makes it easy for any client to deal
  186.     with QD shapes.
  187.     
  188.     source:                    The source QD shape.
  189.     userFunction:            Function for translator to call back with shapes.
  190.     refCon:                    You pass it in, we pass it back to your userFunction.
  191.     stats:                    Statistics generated by the translator.
  192.     
  193. *********************************************/
  194. OSErr QGXTranslateQuickDrawPict(gxShape source, gxShapeSpoolUPP userFunction, 
  195.                                                     long refCon, gxTranslationStatistic *stats)
  196.     {
  197.         OSErr                            status, saveStatus;
  198.         GrafPtr                        curPort;
  199.         TQDTranslationGrafPort    *translationPort;
  200.         gxTag                            geometryTag;
  201.         gxQuickDrawPict            *shapeGeometry;
  202.         FSSpec                        fileSpec;
  203.         AliasHandle                    hAlias;
  204.         short                            fileCount = 1;
  205.         short                            refnum;
  206.         CQDProcs                        spoolProcs;
  207.         PicHandle                    pictToDraw;
  208.         Rect                            destRect;
  209.         gxRectangle                    theRectangle;
  210.         #if GENERATINGPOWERPC
  211.             RoutineDescriptor            getPICTrtnDesc = BUILD_ROUTINE_DESCRIPTOR(uppQDGetPicProcInfo, QGXGetPicProc);
  212.             QDGetPicUPP                    getPICTUPP = (QDGetPicUPP) &getPICTrtnDesc;
  213.         #else
  214.             QDGetPicUPP                    getPICTUPP = (QDGetPicUPP) QGXGetPicProc;
  215.         #endif
  216.         
  217.         require_action((QGXGetShapeType(source) == gxQuickDrawPictType), failed_shapeType, status = -9999;);
  218.  
  219.         /** Make a quickdraw version of the rectangle for the destRect **/
  220.         
  221.         GXGetRectangle(source, &theRectangle);
  222.         destRect.top = theRectangle.top >> 16;
  223.         destRect.bottom  = theRectangle.bottom >> 16;
  224.         destRect.left = theRectangle.left >> 16;
  225.         destRect.right = theRectangle.right >> 16;
  226.         
  227.         /******* Get the QuickDraw pict information from the shape ********/        
  228.  
  229.         GXGetShapeTags(source, gxQuickDrawPictTag, 1, 1, &geometryTag);
  230.         GXLockTag(geometryTag);
  231.         shapeGeometry = (gxQuickDrawPict*)GXGetTagStructure(geometryTag, nil);
  232.         
  233.         nrequire(status = GXGetGraphicsError(nil), failed_getAndLockTag);    
  234.  
  235.         /* Make an alias handle from the data in the tag */
  236.         
  237.         status = PrNewHandle((Handle*)&hAlias, shapeGeometry->alias.aliasRecordSize);
  238.         nrequire(status, failed_newHandle);
  239.         
  240.         BlockMoveData((Ptr)&(shapeGeometry->alias.aliasRecord[0]), *hAlias, shapeGeometry->alias.aliasRecordSize);
  241.         
  242.         /* Get the file spec from the alias handle */
  243.         {
  244.         Boolean    needsUpdate = false;
  245.         status = MatchAlias(    nil, kARMSearch + kARMNoUI + kARMMountVol,
  246.                                     hAlias, &fileCount, &fileSpec, &needsUpdate, nil, nil);
  247.         }
  248.         nrequire(status, failed_Match);
  249.         
  250.         /* Now open the file */
  251.         
  252.         status = FSpOpenDF(&fileSpec, fsRdPerm, &refnum);
  253.         nrequire(status, failed_open);
  254.         
  255.         /* Set the file position */
  256.  
  257.         #if DEBUGLEVEL >= DEBUGFEEDBACK
  258.             dprintf(trace, "file position: %d", (unsigned char *) shapeGeometry->alias.fileOffset);
  259.             dprintf(trace, "qd shape stream size: %d", (unsigned char *) shapeGeometry->dataLength);
  260.         #endif
  261.         
  262.         status = SetFPos(refnum, fsFromStart, shapeGeometry->alias.fileOffset);
  263.         nrequire(status, failed_setPos);
  264.         
  265.         /****** Set up a port for the translator with our buffer in it ******/
  266.  
  267.         status = PrNewPtr((Ptr *) &translationPort, sizeof(TQDTranslationGrafPort));
  268.         nrequire(status, failed_NewPtr);
  269.         
  270.         translationPort->bufferPosition = 0;
  271.         translationPort->bufferSize = 0;
  272.         translationPort->refnum = refnum;
  273.         GetPort(&curPort);
  274.         OpenCPort((CGrafPtr)translationPort);
  275.         SetPort((GrafPtr)translationPort);
  276.         SetStdCProcs(&spoolProcs);
  277.         spoolProcs.getPicProc = getPICTUPP;
  278.         translationPort->thePort.grafProcs = &spoolProcs;
  279.         
  280.         /* Draw the data through the translator */
  281.  
  282.         status = PrNewHandle(&(Handle)pictToDraw, sizeof(Picture));
  283.         nrequire(status, failed_newPicHandle);
  284.         (*pictToDraw)->picFrame = shapeGeometry->srcRect;
  285.     
  286.         GXInstallQDTranslator((GrafPtr)translationPort, shapeGeometry->options, 
  287.                                                                         &shapeGeometry->srcRect,
  288.                                                                         &destRect,
  289.                                                                         shapeGeometry->styleStretch,
  290.                                                                         userFunction, 
  291.                                                                         (void*)refCon);    
  292.         
  293.         DrawPicture(pictToDraw, &shapeGeometry->srcRect);
  294.     
  295.         *stats = GXRemoveQDTranslator((GrafPtr)translationPort, nil);
  296.  
  297.         DisposeHandle((Handle)pictToDraw);
  298.         
  299. failed_newPicHandle:
  300.  
  301.         SetPort(curPort);
  302.  
  303.         CloseCPort((CGrafPtr)translationPort);        // Josh said not doing this can cause crash under display mgr.
  304.         DisposePtr((Ptr)translationPort);
  305.  
  306. failed_NewPtr:
  307. failed_setPos:
  308.  
  309.         saveStatus = FSClose(refnum);
  310.         ncheck(saveStatus);
  311.         if (status == noErr)
  312.             status = saveStatus;
  313.  
  314. failed_open:
  315. failed_Match:
  316.                 
  317.         DisposeHandle((Handle)hAlias);
  318.         
  319. failed_newHandle:
  320.  
  321.         GXUnlockTag(geometryTag);
  322.         
  323. failed_getAndLockTag:
  324. failed_shapeType:
  325.  
  326.         return(status);
  327.     
  328.     }//QGXTranslateQuickDrawPict
  329.